home *** CD-ROM | disk | FTP | other *** search
/ Apple II Magazines (PO) / Nibble Volume 10, No. 04 (1989-04)(MicroSPARC)(Side A).zip / Nibble Volume 10, No. 04 (1989-04)(MicroSPARC)(Side A).po / SC.SYSTEM.S < prev    next >
Text File  |  1996-12-24  |  15KB  |  631 lines

  1.  
  2. ****************************
  3. *                          *
  4. *  SC.SYSTEM SOURCE CODE   *
  5. *  BY SEAN NOLAN           *
  6. *  (C) COPYRIGHT 1989      *
  7. *  MICROSPARC, INC.        *
  8. *  CONCORD, MA 01742       *
  9. *  MERLIN PRO assembler    *
  10. *                          *
  11. ****************************
  12.  
  13.  
  14.           ORG $1000 code runs at $1000 but
  15.                          ;is loaded at $2000 by ProDOS
  16.  
  17.           TYP $FF save as a system file
  18.  
  19.  
  20. ******************************** equates
  21.  
  22.  
  23. READY     = 3 - if date on disk is updated
  24. DAY       = 4 | ProDOS date bytes are broken |
  25. MONTH     = 5 | up into seperate Day, Month, |
  26. YEAR      = 6 | and Year bytes for clarity.  |
  27. WNDLEFT   = $20 left edge of window
  28. CH        = $24 cursor horizontal
  29. A1L       = $3C
  30. A1H       = $3D
  31.  
  32. IN2       = $280
  33.  
  34. RESET     = $3F2
  35.  
  36. MLI       = $BF00 ProDOS entry point
  37. CALLCLOCK = $BF06 JMP to ProDOS clock code
  38. DEVNUM    = $BF30 number of last disk accesssed
  39. DATE      = $BF90 date stored here in packed format
  40. TIME      = $BF92 time stored in minutes : hours
  41. CMDADR    = $BF9C Address+6 of last MLI call
  42.  
  43. KEYBOARD  = $C000 read keyboard
  44. STROBE    = $C010 eat keypress
  45. WRITEBSR1 = $C089 write language card bank 1
  46. NORMROM   = $C08A turn off language card RAM
  47. SETPWRC   = $FB6F fix power-up byte
  48. GOODF8    = $FBB3 identifies II+ vs. IIe/IIc
  49. COUT      = $FDED print character
  50. PRBYTE    = $FDDA print 2-digit hex value
  51. VTABZ     = $FC24 calculate text output for row A
  52. HOME      = $FC58 clear screen
  53. RDKEY     = $FD0C get key with blinking cursor
  54. SETKBD    = $FE89 IN#0
  55. SETVID    = $FE93 PR#0
  56.  
  57.  
  58. ******************************** initialization code
  59.  
  60.  
  61.           JMP START+$1000
  62.           DFB $EE,$EE       indicate startup protocol
  63.           DFB 33       size of startup buffer
  64. STARTUP   DFB 12       length of startup name
  65.           ASC "BASIC.SYSTEM"   default startup program
  66.           DS STARTUP+33-*
  67.           DFB 0
  68.  
  69. *** relocate ourselves down to $1000
  70.  
  71. START     LDY #0
  72.           LDX #5 copy 5 pages of code
  73. :a        LDA $2000,Y
  74. :b        STA $1000,Y
  75.           INY
  76.           BNE :a
  77.           INC :a+$1002
  78.           INC :b+$1002
  79.           DEX
  80.           BNE :a
  81.           JMP START2     jump to relocated code
  82.  
  83. START2    LDX STARTUP     put 00 at the end of the
  84.           TYA            ;   startup name so that
  85.           STA STARTUP+1,X    PRINTAY can print it.
  86.  
  87.           JSR SETKBD IN#0
  88.           JSR SETVID PR#0
  89.  
  90. ***** Set Prefix to this volume
  91.  
  92.           LDA DEVNUM get #of last device accessed
  93.           STA ONLINEn enter with device number in A
  94.  
  95.           JSR MLI
  96.           DFB $C5
  97.           DA ONLINEp
  98.  
  99.           LDY IN2+1 insert a slash before the name
  100.           INY
  101.           TYA
  102.           AND #$0F
  103.           STA IN2
  104.           LDA #'/'
  105.           STA IN2+1
  106.  
  107.           JSR MLI set the prefix
  108.           DFB $C6
  109.           DA SETPFXp
  110.  
  111. ***** Copy the soft clock routine into ProDOS
  112.  
  113.           LDA #$60 Disable the Softclock routine if it
  114.           STA CALLCLOCK is going already.
  115.           LDA CALLCLOCK+1
  116.           STA A1L
  117.           LDA CALLCLOCK+2
  118.           STA A1H
  119.           BIT WRITEBSR1         Turn on language card
  120.           BIT WRITEBSR1
  121.           LDY #SOFTEND-SOFT (size of Softclock)
  122. :loop1    LDA SOFT,Y
  123.           STA (A1L),Y
  124.           DEY
  125.           BPL :loop1
  126.           BIT NORMROM turn off language card
  127.  
  128. **** get date from file on disk
  129.  
  130.           LDA #10 number of parameters
  131.           LDX #$C4 MLI command number
  132.           JSR GETINFO
  133.  
  134.           LDX #3 move 4 bytes into global page
  135. :loop2    LDA MODDATE,X
  136.           STA DATE,X
  137.           DEX
  138.           BPL :loop2
  139.  
  140.           TAY            ;if the DATE byte is 0, there is no date,
  141.           BNE :a so initialize it to February 1, 1989
  142.           LDA #$41
  143.           STA DATE
  144.           LDA #$B2
  145.           STA DATE+1
  146.           INX            ;make X=0
  147.  
  148. :a        STX READY indicate whether date needs to be saved on disk
  149.                          ;if 0, it needs saving. If $FF, all is OK
  150.  
  151.           LDA DATE+1 unpack the date bytes in the global page
  152.           LSR            ;into seperate day, month, and time bytes
  153.           STA YEAR Year is high 7 bits of DATE+1
  154.           LDA DATE
  155.           ROR            ;roll bit 0 of DATE+1 into DATE
  156.           LSR            ;shift 4 more times for month
  157.           LSR
  158.           LSR
  159.           LSR
  160.           STA MONTH
  161.           LDA DATE low 5 bits are day
  162.           AND #%11111
  163.           STA DAY
  164.  
  165. ***** install reset trap
  166.  
  167.           LDA #<RESTART
  168.           STA RESET
  169.           LDA #>RESTART
  170.           STA RESET+1
  171.           JSR SETPWRC fix power-up byte
  172.  
  173.  
  174. ******************************** main menu
  175.  
  176.  
  177. RESTART   LDX #$FF Re-enter here after errors
  178.           TXS            ;and control-RESET
  179.           CLD
  180.           JSR CLOSEALL
  181.  
  182.           JSR HOME
  183.           JSR ROW40
  184.           LDA #11
  185.           STA CH
  186.           LDA #>:text1
  187.           LDY #<:text1
  188.           JSR PRINTAY
  189.           JSR ROW40
  190.           LDA #6
  191.           STA WNDLEFT
  192.           LDA #>:text2
  193.           LDY #<:text2
  194.           JSR PRINTAY
  195.           LDA #>STARTUP+1
  196.           LDY #<STARTUP+1
  197.           JSR PRINTAY
  198.           STA WNDLEFT (A=0 here)
  199.  
  200. :next     JSR PRINTDT print updated date/time
  201.  
  202. :key      LDA KEYBOARD wait for a key
  203.           BPL :key
  204.           STA STROBE
  205.           CMP #"`" convert lower to upper case
  206.           BCC :ok
  207.           SBC #32
  208. :ok       LDX #7 Try to match keypress
  209. :loop     CMP :keys,X with list of valid ones.
  210.           BEQ :match
  211.           DEX
  212.           BPL :loop
  213.           BMI :next if bad keypress, get another
  214.  
  215. :match    TXA
  216.           ASL
  217.           TAX
  218.           LDA :addr,X
  219.           STA :mod+1
  220.           LDA :addr+1,X
  221.           STA :mod+2
  222. :mod      JSR $FFFF self-modified
  223.  
  224.           LDA MONTH rebuild DATE bytes in the ProDOS global
  225.           ASL            ;page in case we changed them by pressing
  226.           ASL            ;an arrow key
  227.           ASL
  228.           ASL
  229.           ASL
  230.           ORA DAY
  231.           STA DATE carry holds high bit of month
  232.           LDA YEAR
  233.           ROL
  234.           STA DATE+1
  235.           BCC :next branch always
  236.  
  237. :text1    DFB $8A
  238.           ASC "Apple ][ Softclock"
  239.           DFB $8D,$8D
  240.           ASC "BY SEAN NOLAN  (C)1989 MICROSPARC, INC."
  241.           DFB $8D,0
  242.  
  243. :text2    DFB $8D,$8D,$8D,$8D,$8D,$8D,$8D
  244.           ASC "Arrow keys change the date"
  245.           DFB $8D,$8D
  246.           ASC "T - Change the time"
  247.           DFB $8D,$8D
  248.           ASC "S - Save date/time to disk"
  249.           DFB $8D,$8D
  250.           ASC "Q - Quit"
  251.           DFB $8D,$8D
  252.           ASC "R - Run "
  253.           DFB 0
  254.  
  255. :keys     DFB $95,$88,$8A,$8B,"T","S","Q","R"
  256.  
  257. :addr     DA INCDAY next day
  258.           DA DECDAY previous day
  259.           DA INCMONTH next month
  260.           DA DECMONTH previous month
  261.           DA GETTIME input time
  262.           DA SETINFO save date to disk
  263.           DA QUIT quit code
  264.           DA GOBASIC go to BASIC.SYSTEM
  265.  
  266.  
  267. ******************************** change the date
  268.  
  269.  
  270. DECDAY    LSR READY flag that date has changed
  271.           DEC DAY
  272.           BNE :a
  273.           JSR DECMONTH
  274.           LDX MONTH
  275.           LDA DAYS-1,X
  276.           STA DAY
  277. :a        RTS
  278.  
  279. DECMONTH  LSR READY
  280.           DEC MONTH backup to previous month
  281.           BNE :a
  282.           LDA #12
  283.           STA MONTH December
  284.           DEC YEAR backup to previous year
  285.           BPL :a fix year at the turn of the century
  286.           LDA #99
  287.           STA YEAR
  288. :a        RTS
  289.  
  290. INCDAY    LSR READY
  291.           LDX MONTH
  292.           LDA DAY
  293.           INC DAY increment the day
  294.           CMP DAYS-1,X if we were not at monthly limit,
  295.           BNE :a then exit.
  296.           LDA #1
  297.           STA DAY Otherwise, set day to 1
  298.           JSR INCMONTH and inc the month
  299. :a        RTS
  300.  
  301. INCMONTH  LSR READY
  302.           INC MONTH
  303.           LDA MONTH
  304.           CMP #13
  305.           BNE :a
  306.           LDA #1
  307.           STA MONTH
  308.           INC YEAR
  309.           LDA YEAR
  310.           EOR #99 fix year at the turn of the century
  311.           BNE :a
  312.           STA YEAR
  313. :a        RTS
  314.  
  315. DAYS      DFB 31,29,31,30,31,30
  316.           DFB 31,31,30,31,30,31
  317.  
  318.  
  319. ******************************** change the time
  320.  
  321.  
  322. GETTIME   LDA #7 position cursor at CV=7, CH=23
  323.           JSR VTABZ
  324.           LDA #23
  325.           STA CH
  326.           LDX #5 get up to 4 keypresses
  327.  
  328. :a        JSR RDKEY get a keypress (with cursor visable)
  329.           CMP #$8D skip ahead if RETURN...
  330.           BEQ :c
  331.           CMP #$9B ...or cancel entirely if ESCAPE
  332.           BEQ :e
  333.           CMP #"0" reject other keys except digits
  334.           BCC :a
  335.           CMP #"9"+1
  336.           BCS :a
  337.  
  338. :b        LSR READY flag that time has changed
  339.           JSR COUT if digit gotten, print it
  340.           DEX
  341.           LDA #":"
  342.           CPX #3 after getting 2nd character, skip the colen
  343.           BEQ :b
  344.           TXA
  345.           BNE :a
  346.                          ;desired time is now on the screen
  347.  
  348. :c        LDA $780+23 pick the hour off of the screen
  349.           LDY $780+24 and convert to a single byte
  350.           JSR CONVERT
  351.           CPX #24 make sure hour is in range
  352.           BCS :d
  353.           STX TIME+1
  354. :d        LDA $780+26 do the same for the minutes
  355.           LDY $780+27
  356.           JSR CONVERT
  357.           CPX #60 make sure minutes is in range
  358.           BCS :e
  359.           STX TIME
  360. :e        RTS
  361.  
  362. * Enter with ASCII values for number in A (high decimal digit)
  363. * and Y (low decimal digit). Exit with hex byte in X.
  364. * Called only by GETTIME
  365.  
  366. CONVERT   ASL            ;shift high digit into high nybble
  367.           ASL
  368.           ASL
  369.           ASL
  370.           STA A1L
  371.           TYA            ;isolate low digit
  372.           AND #$0F
  373.           ORA A1L combine with high - now have BCD value.
  374.           SED            ;convert BCD Accumulator to hex X register
  375.           LDX #$FF
  376.           SEC
  377. :loop     SBC #1
  378.           INX
  379.           BCS :loop
  380.           CLD
  381.           RTS
  382.  
  383.  
  384. ******************************** store date/time to disk
  385.  
  386.  
  387. SETINFO   LDX #3 move date & time to DTplist
  388. :loop     LDA DATE,X
  389.           STA MODDATE,X
  390.           DEX
  391.           BPL :loop
  392.  
  393.           STX READY flag that date saved
  394.  
  395.           LDA #7 number of parameters
  396.           LDX #$C3 MLI command number for set file info
  397.  
  398. GETINFO   STA :p this code is called on startup to read
  399.           STX :a the date stored in the MOD TIME field.
  400.           JSR MLI
  401. :a        DFB 0
  402.           DA :p
  403.           JMP ERROR?
  404.  
  405.  
  406. *** ProDOS parameter list for date and time
  407. *
  408. * Used whenever the time is written to or read from the
  409. * disk.  The time is stored as the MOD TIME field of the
  410. * file "SC.SYSTEM" on the disk.
  411.  
  412.  
  413. :p        DFB 0 self-modified
  414.           DA NAME pointer to name
  415.           DFB $C3 access code
  416.           DFB $FF file type code
  417.           DA 0 aux type
  418.           DFB $02 storage type
  419.           DA 0 blocks used
  420. MODDATE   DA 0 mod date returned here
  421.           DA 0 mod time returned here
  422.           DFB 0,0,0,0 create date & time
  423.  
  424. NAME      DFB 9 (leading length byte)
  425.           ASC "SC.SYSTEM"
  426.  
  427.  
  428. ******************************** Quit
  429.  
  430.  
  431. QUIT      JSR TURNON Save date to disk
  432.                          ;and turn on Softclock
  433.           JSR MLI quit
  434.           DFB $65
  435.           DA :a
  436. :a        DFB 4
  437.           DFB 0,0,0,0,0,0
  438.  
  439.  
  440. TURNON    BIT READY if date or time has changed
  441.           BMI :ok then update date on disk.
  442.           JSR SETINFO
  443.  
  444. :ok       LDA #$4C change entering RTS to a JMP
  445.           STA CALLCLOCK to turn on Softclock
  446.           RTS
  447.  
  448.  
  449. ******************************** Go to BASIC
  450. * (or any other SYSTEM program whose name was
  451. * placed in the startup buffer of this program)
  452.  
  453. GOBASIC   JSR MLI open the startup file
  454.           DFB $C8
  455.           DA :open
  456.           JSR ERROR?
  457.  
  458.           LDA :on copy reference number
  459.           STA :rn
  460.  
  461.           JSR MLI read it in
  462.           DFB $CA
  463.           DA :read
  464.           JSR ERROR?
  465.  
  466.           JSR CLOSEALL close it
  467.  
  468.           JSR TURNON Save date to disk
  469.                          ;and turn on Softclock
  470.           JMP $2000 Jump to next system program
  471.  
  472. :open     DFB 3
  473.           DA STARTUP name of program to open
  474.           DA $800 i/o buffer
  475. :on       DFB 0 reference number result here
  476.  
  477. :read     DFB 4
  478. :rn       DFB 0 reference number
  479.           DA $2000 put system program here
  480.           DA $9F00 request largest possible size
  481.           DA 0 length read in returned here
  482.  
  483.  
  484. ******************************** character output
  485.  
  486.  
  487. **** Print string whose address is passed in AY
  488. **** Always exit with A=0
  489.  
  490. PRINTAY   STA A1H
  491.           STY A1L
  492.           LDY #0
  493. :loop     LDA (A1L),Y
  494.           BEQ :rts
  495.           ORA #$80
  496.           BIT GOODF8 if running on a II or II+,
  497.           BPL :ok change lower-case to upper.
  498.           CMP #$E0
  499.           BCC :ok
  500.           SBC #32
  501. :ok       JSR COUT
  502.           INY
  503.           BNE :loop always
  504. :rts      RTS
  505.  
  506.  
  507. **** Print 40 underlines
  508.  
  509. ROW40     LDX #40
  510.           LDA #"_"
  511. :loop     JSR COUT
  512.           DEX
  513.           BNE :loop
  514.           RTS
  515.  
  516.  
  517. ******************************** the soft-clock routine
  518. * This is installed deep into the bowels of ProDOS, and
  519. * hangs around long after this program is only a memory.
  520.  
  521. SOFT      CLD
  522.           SEC            ;Only inc the time if a close
  523.           LDA CMDADR file MLI call is in progress.
  524.           SBC #3 This way programs that call
  525.           STA A1L GETTIME continuously won't make
  526.           LDA CMDADR+1 time race by.
  527.           SBC #0
  528.           STA A1H
  529.           LDX #0
  530.           LDA (A1L,X)
  531.           CMP #$CC if MLI call is not CLOSE, exit
  532.           BNE :exit
  533.  
  534.           INC TIME inc minute by 1
  535.           LDA TIME
  536.           EOR #60
  537.           BNE :exit
  538.           STA TIME if even hour reached
  539.           INC TIME+1
  540.           LDA TIME+1
  541.           EOR #24 If even day reached go back
  542.           BNE :exit to 0:00.  Sorry, the clock
  543.           STA TIME+1 will not change the date at
  544. :exit     CLC            ;midnight.
  545. SOFTEND   RTS
  546.  
  547.  
  548. ******************************** Print date/time
  549.  
  550.  
  551. PRINTDT   LDA #12
  552.           STA CH
  553.           LDA #7
  554.           JSR VTABZ
  555.           LDX DAY print day
  556.           JSR :printdec
  557.  
  558.           LDA #"-"
  559.           JSR COUT
  560.           LDA MONTH get month...
  561.           ASL
  562.           ADC MONTH ...times 3
  563.           TAX
  564.           LDY #3 print 3 characters for month
  565. :loop1    LDA :months-3,X
  566.           JSR COUT
  567.           INX
  568.           DEY
  569.           BNE :loop1
  570.  
  571.           LDA #"-"
  572.           JSR COUT
  573.           LDX YEAR print year
  574.           JSR :printdec
  575.  
  576.           INC CH
  577.           INC CH
  578.           LDX TIME+1 print hours
  579.           JSR :printdec
  580.           LDA #":"
  581.           JSR COUT
  582.           LDX TIME print minutes
  583.  
  584. :printdec SED            ;convert HEX > BCD
  585.           LDA #$99 enter with value to convert in X
  586. :loop2    CLC            ;exits with BCD byte in Accumulator
  587.           ADC #1
  588.           DEX
  589.           BPL :loop2
  590.           CLD
  591.           JMP PRBYTE print it
  592.  
  593. :months   ASC "JANFEBMARAPRMAYJUN"
  594.           ASC "JULAUGSEPOCTNOVDEC"
  595.  
  596.  
  597. ******************************** error trapper
  598.  
  599.  
  600. ERROR?    BCC :rts
  601.           PHA            ;remember error number
  602.  
  603.           JSR HOME
  604.           LDA #11
  605.           STA CH
  606.           JSR VTABZ
  607.           LDA #>:text
  608.           LDY #<:text
  609.           JSR PRINTAY
  610.           PLA            ;get error number
  611.           JSR PRBYTE
  612.           INC CH
  613.           JSR RDKEY
  614.           JMP RESTART
  615. :rts      RTS
  616.  
  617. :text     ASC "ProDOS error $"
  618.           DFB 0
  619.  
  620. ONLINEp   DFB 2 online parameter list
  621. ONLINEn   DFB 0 device number
  622.           DA IN2+1
  623.  
  624. SETPFXp   DFB 1 set prefix parameter list
  625.           DA IN2
  626. CLOSEALL  JSR MLI close all files
  627.           DFB $CC
  628.           DA :a
  629.           RTS
  630. :a        DFB 1,0
  631.